package com.example.springbootcaffeinedemo.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springbootcaffeinedemo.entity.Account1;
import com.example.springbootcaffeinedemo.mapper.Account1Mapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * Created by IntelliJ IDEA2022.3.2
 * @Author: Tenghw
 * @Date: 2023/04/18  16:50
 * @Description:
 */
@Slf4j
@Service
public class Account1Service extends ServiceImpl<Account1Mapper,Account1> {
    @Autowired
    Account1Mapper account1Mapper;

    // 初始化Caffeine
    private final Cache<Integer, Account1> cache = Caffeine.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(100, TimeUnit.SECONDS)
            .build();

    public Account1 queryById1(Integer id) {
         cache.get(id, id1 -> {
            log.warn("账户id={}本地缓存不存在，重新计算...", id1);
            return new Account1(id1, "姬无命", "123", 0, "备注信息：123");
        });
        return cache.getIfPresent(id);
    }

    public boolean insertAccount1(Integer id) {
        Account1 account1 = new Account1(id,"李寻欢","123",0,"");
        cache.put(id,account1);
        return true;
    }

    /**
     * 这里的key = "#id"用到了Spring EL表达式，即该缓存的key为：account1Cache::id变量的值
     */
    @Cacheable(value = "account1Cache", key = "#id", sync = true)
    public Account1 queryById2(Integer id) {
        log.info("查询数据库中account的数据，入参id: {}",id);
        Account1 account1 = new Account1();
        account1.setId(1001);
        account1.setName("叶开");
        account1.setPassword("123");
        account1.setIntegral(0);
        account1.setRemarks(StringUtils.EMPTY);
        return account1;
    }

    /**
     * 当缓存失效（比如过期、不存在等原因）时，直接操作数据库，向库中插入数据；将执行结果以键值对的形式存入指定的Cache缓存中。
     */
    @Transactional(rollbackFor = Exception.class)
    @CachePut(value = "account1Cache", key = "#account1.id")
    public Account1 saveAccount1(Account1 account1) {
        log.info("往数据库插入一条账户记录");
        int insert = account1Mapper.insert(account1);
        if(insert==0){
            throw new RuntimeException("插入失败！");
        }
        return account1;
    }

    /**
     * 清除缓存中指定的key
     * 若allEntries = true,则删除缓存中所有的key,此时 @CacheEvict中key设置的属性无效了
     */
    @CacheEvict(value = "account1Cache", key = "#id",allEntries = false)
    public void delUser(Integer id) {
        log.warn("删除用户本地缓存account1Cache的数据，删除的key:{} ","account1Cache::"+id);
        //cache.invalidate("account1Cache::"+id); 不需要执行，@CacheEvict自动帮你清除的
    }
}
